using System;
using Kag.NeuralNetworks;

namespace dvrz {
  class Test {
    const int nInput=2, nOutput=1;
    float[] sample=new float[nInput+nOutput];
    Perceptron perceptron=new Perceptron(nInput, nOutput, new SigmoidActivation());
    void CreateSample(ListQuote quotes, int iList) {
      sample[0]=quotes[iList-1].High-quotes[iList-2].High;
      sample[1]=quotes[iList].High-quotes[iList-1].High;
      sample[2]=quotes[iList+1].High-quotes[iList].High+0.5f;
    }
    public void Learn(ListQuote quotes) {
      Tools.RandomizeWeights(perceptron, 1/3f);
      float step=1.06f;
      const float end=(float)1e-6;
      int iEpoch=0;
      float besterr=float.MaxValue;
      perceptron.Rate=0.2f;
      while( true ) {
        float err=0;
        for( int i=2; i<quotes.Count/2; ++i ) {
          CreateSample(quotes, i);
          perceptron.Sample=sample;
          perceptron.Forward();
          perceptron.Backward();
          for( int io=0; io<nOutput; ++io ) {
            float d=perceptron.Sample[nInput+io]-perceptron.Output[io];
            err+=d*d;
          }
        }
        if( err<besterr ) {
          besterr=err;
          perceptron.Rate*=step;
          perceptron.Backup();
        }
        else {
          perceptron.Rate/=step;
          perceptron.Restore();
        }
        iEpoch++;
        if( perceptron.Rate<end ) break;
      }
    }
    public float Predict(ListQuote quotes, int iList) {
      CreateSample(quotes, iList);
      perceptron.Sample=sample;
      perceptron.Forward();
      return perceptron.Output[0]-0.5f+perceptron.Sample[1];
    }
  }
}